import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;



/*@uses: program to implemnet "score" funtion given by Dr. Ashish
 * 
 * ------------------------------------------------------------------
 *@SET@@@@@@@
 *@1: Change name of score table
 *@2: sum   
 *------------------------------------------------------------------
 * */
public class h1_1_accuracy
{
   public Connection conn =  null;
   private String dbname = "2jboss";
   private String passwd= "123";
   private String userid = "root"; 
   ArrayList<String>  bugids = null;	
   public String score_table = "h4_score";//<<<<<<please set
   public String sum = "sum1";//<<<<<<<<please set
	
   public void process(Connection conn)
   {
	   bugids =  new ArrayList<String>();
	   bugids =  get_bugids(conn,bugids,score_table);
	   System.out.println("No Of bugids = "+bugids.size());
	   
	   
	   int No_of_bugids = 0; 
	   double avg_algo_score =0;
	   double algo_score = 0;
	   double highest_score = 0;
	   int more_than_90 = 0;
	   
	   for(int i =0;i<bugids.size();i++)
	   {
		   String bugid = bugids.get(i);
		   String bug_version_table  =  get_table(conn,bugid,score_table);		 
		   System.out.println("Bugid = "+bugid +" table="+bug_version_table);
		   ArrayList<String> bug_valid_svn_file = get_bug_svn_valid_files(conn,bugid,bug_version_table);
		   
		   if(bug_valid_svn_file.size()!=0)
		   {
			   No_of_bugids++;
			   ArrayList<file_and_rank> ranked_table_files =  get_ranked_files(bugid,conn,score_table);
			   
			   int highest_rank= get_highest_rank(bug_valid_svn_file,ranked_table_files,bugid);
			   
			   int table_size =  ranked_table_files.size();
			   
			   
			   double temp_score = ((table_size-highest_rank)*1.0/table_size)*100;
			   
			   algo_score = algo_score+temp_score;
			   
			   if(highest_score<temp_score)
			   {
				   highest_score =  temp_score;
			   }
			   if(temp_score>=90.0)
			   {
				   more_than_90++;
			   }
			  
			   //insert_db(bugid,bug_version_table,bug_valid_svn_file,table_size,highest_rank,temp_score,conn);
		   }
		   else
		   {
			   System.out.println("No svn file for= "+ bugid);
		   }
		   
		   //if(bugid.equalsIgnoreCase("jbas-1070"))
			   //intr();
				   
	   }//for
	
	   
	   avg_algo_score = algo_score/No_of_bugids;
	   System.out.println("final bugids="+No_of_bugids);
	   System.out.println("System effectiveness(Avg Algo Score) = "+avg_algo_score);
	   System.out.println("Highest effectiveness="+highest_score); 
	   
	   double more_than_90_percent = ((more_than_90 *1.0)/No_of_bugids)*100; 
	   System.out.println("No of bugs pruning more than 90%="+more_than_90);
	   System.out.println("More than 90 percent="+more_than_90_percent);
   }

   
public void insert_db(String bugid, String bug_version_table,ArrayList<String> bug_valid_svn_file, 
		int table_size, int highest_rank,double temp_score, Connection conn)
{
   Statement stmt =  null;	
   try
      {
	     stmt  =  conn.createStatement();
  
     // for(int i=0;i<bug_valid_svn_file.size();i++)
	    // {
	       // String file = bug_valid_svn_file.get(i);
	        String file = "Not Considering";
            String str = "insert into h1_1_acc_temp values('"+bugid+"',"+(1)+",'"+file+"','"+bug_version_table+"',"+table_size+
                   ","+highest_rank+","+temp_score+")";
            stmt.execute(str);      
       //} 
	
   if(stmt!=null)
	   stmt.close();
   
   } catch (SQLException e) 
   {	e.printStackTrace(); }
}//insert_db

//It will return the file with highest rank reported by our system to calculate effectiveness of the system
public int get_highest_rank(ArrayList<String> bug_valid_svn_file, ArrayList<file_and_rank> ranked_table_files, String bugid) 
{
 
	int highest_rank = -1;
     
	for(int i=0;i<bug_valid_svn_file.size();i++)
	{
		 String svn_file = bug_valid_svn_file.get(i);
		 svn_file = svn_file.replace(".java", "");
		 
		for(int j=0;j<ranked_table_files.size();j++)
		{
			String ranked_file=ranked_table_files.get(j).file_name;
			if(svn_file.equalsIgnoreCase(ranked_file))
			{
				int file_rank = ranked_table_files.get(j).rank;
				
				if(file_rank>highest_rank)
				{
					highest_rank = file_rank;
				}
				break;
			}//if
		}
	}
 
 return highest_rank;
	
}


//get distinct ranked files for a particluar bug   
public ArrayList<file_and_rank> get_ranked_files(String bugid, Connection conn, String SCORE_TABLE) 
{
	ArrayList<file_and_rank> ranked_table_files =  new ArrayList<file_and_rank>();
	
	String  rank_q ="select file_name,"+ sum +" from "+ SCORE_TABLE +" where bugid = '"+bugid+"' order by "+ sum +" desc,file_name";
	
	Statement stmt =  null;
	try 
	{
		stmt  = conn.createStatement();
		stmt.execute(rank_q);
		ResultSet rs =  stmt.getResultSet();
		int rank =0;
		while(rs.next())
		{
			rank++;
			String file_name = rs.getString("file_name");
			double score =  rs.getDouble(sum);
			ranked_table_files.add(new file_and_rank(file_name,rank,score));
		}
	} catch (SQLException e) 
	{ e.printStackTrace(); }
	
	/*if(bugid.equalsIgnoreCase("jbas-1070"))
	{
		for(int i=0;i<ranked_table_files.size()&i<4196;i++)
		{
			String f =  ranked_table_files.get(i).file_name;
			int rank =  ranked_table_files.get(i).rank;
			double score =  ranked_table_files.get(i).score;
			System.out.println("file name="+f+" rank="+rank+" score="+score);
		}
		
	}*/
	
	return ranked_table_files;
}

// Method to retrive valid svn files modified for a bug, becuase it might happen that some files
 // modified for a aparticular bug may not be present in the affected version.
public ArrayList<String> get_bug_svn_valid_files(Connection conn, String bugid, String table) 
{
	ArrayList<String> valid_svn_files = new ArrayList<String>(); 
	ArrayList<String> table_files = get_table_files(table,conn);
	String bug_svn_q ="select distinct bugid, file_name from  bug_svn_m_file  where bugid='"+bugid+"'";
	//System.out.println("Bug_svn_q="+bug_svn_q);
	   
	   Statement stmt2;
	   try 
	   {
		stmt2 = conn.createStatement();
		stmt2.execute(bug_svn_q);
		ResultSet rs2 =  stmt2.getResultSet();
		while(rs2.next())
		{
			String file_name = rs2.getString("file_name");			
			boolean valid = is_valid_table_file(table_files,file_name);
			
			if(valid)
				valid_svn_files.add(file_name);
			
		}
		
		if(rs2!=  null)
			rs2.close();
		if(stmt2!=null)
			stmt2.close();
		   
	   } catch (SQLException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}

	return valid_svn_files;
}

public boolean is_valid_table_file(ArrayList<String> table_files,String file_name)
{
   boolean valid  = false;	
   
   for(int i=0;i<table_files.size();i++)
   {
	   String table_file  =  table_files.get(i);
	   if(file_name.equalsIgnoreCase(table_file))
	   {
		  // System.out.println("file name = "+file_name);
		  // System.out.println("table_file="+table_file);
		   valid =  true;
		   break;
	   }
   }
   
   return valid;
}

//to check that files in modified by a bug actually exists in the table we are considering
public ArrayList<String>  get_table_files(String table, Connection conn)
{
	
	ArrayList<String> table_files =  new ArrayList<String>();
	
	String table_file_q  =  "select distinct file_name from "+table;
	//System.out.println("Table q = "+table_file_q);
	Statement stmt  =  null;
	try
	{
		stmt=conn.createStatement();
		stmt.execute(table_file_q);
		ResultSet rs =  stmt.getResultSet();
		while(rs.next())
		{
			String file_name =  rs.getString("file_name");
			//file_name =  file_name.replace(".java", "").toLowerCase();			
			table_files.add(file_name); 
		}
		
		if(rs!=null)
			rs.close();
		
		if(stmt!=null)
			stmt.close();
		
	} catch (SQLException e) 
	{e.printStackTrace(); }
	
	
	return table_files;
}

public String get_table(Connection conn, String bugid, String SCORE_TABLE)
{

	  String table_q = "select `table` from "+ SCORE_TABLE + " where bugid = '"+bugid+"' limit 0,1";
	  //System.out.println("table query="+table_q);
	  String table = "";
	  Statement stmt = null;	
	  try 
	  {
		stmt  = conn.createStatement();
		stmt.execute(table_q);
		ResultSet rs =  stmt.getResultSet();
		while(rs.next())
		{
		   table = rs.getString("table");	
		}
		
		
		if(rs!=null)
			rs.close();		
		if(stmt!=null)
			stmt.close();
		
	  } catch (SQLException e) 
	  { e.printStackTrace();}
	  
	  return table;
}

public ArrayList<String> get_bugids(Connection conn, ArrayList<String> bugids, String SCORE_TABLE) 
{

	 System.out.println("I am here");
	  String bug_q = "select distinct bugid from "+SCORE_TABLE;
	  
	  Statement stmt = null;	
	  try 
	  {
		stmt  = conn.createStatement();
		stmt.execute(bug_q);
		ResultSet rs =  stmt.getResultSet();
		while(rs.next())
		{
			String bugid = rs.getString("bugid");
			bugids.add(bugid);
		}
		
		
		if(rs!=null)
			rs.close();		
		if(stmt!=null)
			stmt.close();
		
	  } catch (SQLException e) 
	  { e.printStackTrace();}
	  return bugids;
}


public void intr()
 {
	 BufferedReader br =  new BufferedReader(new InputStreamReader(System.in));
	 System.out.println("INTR");
	 try {
		br.readLine();
	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	 
 }
public static void main(String args[])
{
		h1_1_accuracy h1 = new h1_1_accuracy();
		db_conn db  =  new db_conn();
		h1.conn  = db.connect(h1.dbname, h1.userid, h1.passwd);
		h1.process(h1.conn);
	    db.close(h1.conn);
}


 
}//class
